<?php


/**
 * Notes:
 * PROJECT_NAME : ERP v1.8 重构erp
 * User: 夏鱼儿<397072174@qq.com>
 * Date: 2024/5/9
 * Time: 15:50
 */

namespace app\mini\controller\order;

use app\company\model\CompanyGoodsRule;
use app\mini\controller\Base;
use app\mini\model\Store;
use app\mini\model\StoreCart;
use app\mini\model\StoreOrder;
use app\mini\model\StoreOrderDetail;
use app\mini\model\CompanyGoodsChangeLog;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Cache;
use think\Response;
use WePayV3\Order;

/**
 * 收银台/结算台/结账台
 */
class Checkout extends Base
{
    protected string $address = '';    //接货地址
    protected mixed  $goods;           //商品明细
    protected float  $balance = 0.00;  //余额
    protected bool   $bill    = false; //账期支付信息
    //大额支付信息 默认配置
    protected array $large = [];

    protected string $cart_ids    = '';//购物车ID
    protected int    $order_id    = 0; //订单
    protected array  $goods_rules = [];//规格ID:数量

    protected array $wx_result = [];//微信支付订单

    public function initialize()
    {
        parent::initialize();//如果没有这,会先执行子类的initialize
        if ($this->userInfo->is_salesman == 2) {
            //初始化收货地址 当前用户不是销售员时，收货地址为店铺地址
            $this->address = $this->userInfo->store()
                                            ->value('address');
            //店铺是否开启账期支付
            if ($this->userInfo->store()
                               ->value('is_on_credit') == 1) $this->bill = true;
        }
        //初始化余额
        $this->balance = bcadd($this->userInfo->storeUserAccountO()
                                              ->value('money'), 0, 2);
        //初始化来源参数
        $this->cart_ids    = $this->request->param('cart_ids', '');
        $this->order_id    = $this->request->param('order_id', 0);
        $this->goods_rules = $this->request->param('goods_rules', []);
        $this->large       = config('platform.large');
    }

    /**
     * 结算台
     * @return Response
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function index(): Response
    {
        $field = 'goods_id,goods_rule_id,quantity,money,amount';
        //来源为购物车
        if ($this->cart_ids) {
            $this->goods = StoreCart::whereIn('id', $this->cart_ids)
                                    ->field($field)
                                    ->select()
                                    ->each(function ($item) {
                                        $item->goods_name  = $item->goods()
                                                                  ->withTrashed()
                                                                  ->value('name');
                                        $item->goods_image = $item->goodsRule()
                                                                  ->withTrashed()
                                                                  ->value('img');
                                        $item->spec_name   = $item->goodsRule()
                                                                  ->withTrashed()
                                                                  ->value('spec_name');
                                    });
        }
        //来源为立即购买
        if ($this->goods_rules) {
            //商品基本信息
            $field       = 'goods_id,goods_rule_id,money';
            $this->goods = CompanyGoodsRule::gs()
                                           ->goodsRuleId($this->goods_rules['goods_rule_id'])
                                           ->field($field)
                                           ->select()
                                           ->each(function ($item) {
                                               $item->goods_name  = $item->goods()
                                                                         ->withTrashed()
                                                                         ->value('name');
                                               $item->goods_image = $item->goodsRule()
                                                                         ->withTrashed()
                                                                         ->value('img');
                                               $item->spec_name   = $item->goodsRule()
                                                                         ->withTrashed()
                                                                         ->value('spec_name');
                                               $item->quantity    = $this->goods_rules['quantity'];
                                               $item->amount      = bcmul($item->money, $item->quantity, 2);
                                           });
        }
        //来源为订单详情
        if ($this->order_id) {
            $this->goods = StoreOrderDetail::where('store_order_id', $this->order_id)
                                           ->field($field)
                                           ->select()
                                           ->each(function ($item) {
                                               $item->goods_name  = $item->goods()
                                                                         ->withTrashed()
                                                                         ->value('name');
                                               $item->goods_image = $item->goodsRule()
                                                                         ->withTrashed()
                                                                         ->value('img');
                                               $item->spec_name   = $item->goodsRule()
                                                                         ->withTrashed()
                                                                         ->value('spec_name');
                                           });

            //重新生成订单号
            $order     = StoreOrder::where('id', $this->order_id)
                                   ->find();
            $order->no = "XS" . date('YmdHis') . mt_rand(100000, 999999);
            $order->save();

            //微信支付配置
            $config = getWxConfig(['appid' => $this->appid]);
            // 4. 组装支付参数
            $total           = $order->storeOrderDetails()
                                     ->sum('amount') * 100;
            $this->wx_result = Order::instance($config)
                                    ->create('jsapi', [
                                        'appid'        => $config['appid'],
                                        'mchid'        => $config['mch_id'],
                                        'description'  => '商品描述',//商品描述
                                        'out_trade_no' => $order->no,//订单号
                                        'notify_url'   => config('platform.notify_url'),//回调地址
                                        //用户openid 唯一标识
                                        'payer'        => ['openid' => $this->userInfo->storeUserOauths()
                                                                                      ->where('oauth_type', 1)
                                                                                      ->value('oauth_id')],
                                        'amount'       => ['total' => (int)$total, 'currency' => 'CNY'],//total 总金额 单位分
                                    ]);
        }

        $arrObj = get_object_vars($this);// 获取当前对象的所有属性
        $keys   = ['address', 'goods', 'balance', 'bill', 'large', 'cart_ids', 'order_id', 'goods_rules', 'wx_result'];
        $add    = array_intersect_key($arrObj, array_flip($keys));// 过滤出指定的属性
        return $this->success('成功', $add);
    }

    // 业务员购物车订单结算中心
    public function salesmanIndex(): Response
    {
        $order        = $this->request->param('order');
        $send = $this->request->param('send') ?? [];
        $field        = 'goods_id,goods_rule_id,quantity,money,amount';
        $is_on_credit = [];
        foreach ($order as &$item) {
            $store              = Store::find($item['store_id']);
            $is_on_credit[]     = $store->is_on_credit;
            $item['store_name'] = $store->name;
            $item['goods']      = StoreCart::whereIn('id', explode(',', $item['cart_ids']))
                                           ->field($field)
                                           ->select()
                                           ->each(function ($vo) use ($item) {
                                               $goods = $vo->goods()
                                                           ->withTrashed()
                                                           ->find();
                                               $specs = $vo->goodsRule()
                                                           ->withTrashed()
                                                           ->find();
                                               // 查询规格商品上一次修改的价格
                                               // 2024.09.23修改此方法
                                               $changeLog = $this->getLastChangeLog($item['store_id'], $specs['id']);
                                               if($changeLog){
                                                   $edit_money = $changeLog['new_money'];
                                               }else{
                                                   $edit_money = Cache::get($this->user_id . '_' . $item['store_id'] . '_' . $specs['id']);
                                               }
                                               if ($edit_money) {
                                                   $vo->edit_money = $edit_money;
                                                   $vo->amount     = bcmul($vo->edit_money, $vo->quantity, 2);

                                               }
                                               $vo->goods_name       = $goods->name;
                                               $vo->goods_cate_id    = $goods->goods_cate_id;
                                               $vo->goods_image      = $vo->goodsRule()
                                                                          ->withTrashed()
                                                                          ->value('img');
                                               $vo->spec_name        = $specs->spec_name;
                                               $vo->purchasing_price = $specs->purchasing_price;
                                               $vo->is_send = Storeorder::NOT_SEND_GOODS;
                                           })
                                           ->toArray();
                                           
            if($send){
                $send_goods = $this->appendGoods($send,$store->company_id);
                $item['goods'] = array_merge($item['goods'], $send_goods);
            }                               
            $item['amount']     = array_sum(array_column($item['goods'], 'amount'));
            $item['quantity']   = array_sum(array_column($item['goods'], 'quantity'));
        }
        
        $total_amount   = array_sum(array_column($order, 'amount'));
        $total_quantity = array_sum(array_column($order, 'quantity'));
        $bill           = !in_array(2, $is_on_credit);
        $balance        = $this->balance;
        $large          = $this->large;
        $unique         = md5("check_order_" . $this->user_id . uniqid());
        $list           = ['order'          => $order, 'large' => $large, 'total_amount' => $total_amount,
                           'total_quantity' => $total_quantity, 'bill' => $bill,
                           'balance'        => $balance, 'unique' => $unique];
        Cache::set($unique, $list, 7200);
        return $this->success('成功', $list);
    }

    // 业务员立即下单结算台
    public function salesmanSettle(): Response
    {
        $param = $this->request->param();
        $send = $this->request->param('send') ?? [];
        //商品基本信息
        $field          = 'goods_id,goods_rule_id,money';
        $store          = Store::find($param['store_id']);
        $goods          = CompanyGoodsRule::gs()
                                          ->goodsRuleId($param['goods_rule_id'])
                                          ->field($field)
                                          ->select()
                                          ->each(function ($item) use ($param) {
                                              $goods                  = $item->goods()
                                                                             ->withTrashed()
                                                                             ->find();
                                              $specs                  = $item->goodsRule()
                                                                             ->withTrashed()
                                                                             ->find();
                                              $item->goods_name       = $goods->name;
                                              $item->goods_cate_id    = $goods->goods_cate_id;
                                              $item->goods_image      = $item->goodsRule()
                                                                             ->withTrashed()
                                                                             ->value('img');
                                              $item->spec_name        = $specs->spec_name;
                                              $item->purchasing_price = $specs->purchasing_price;
                                              $item->quantity         = $param['quantity'] ?? 1;
                                              $item->amount           = bcmul($item->money, $item->quantity, 2);
                                              $item->is_send = Storeorder::NOT_SEND_GOODS;// 非赠送商品，赠送为2
                                              // 判断商品上一次是否有修改价格
                                              // 2024.09.23修改此方法
                                              $changeLog = $this->getLastChangeLog($param['store_id'], $specs['id']);
                                              if($changeLog){
                                                $edit_money = $changeLog['new_money'];
                                              }else{
                                                $edit_money = Cache::get($this->user_id . '_' . $param['store_id'] . '_' . $param['goods_rule_id']);
                                              }
                                              if ($edit_money) {
                                                  $item->edit_money = $edit_money;
                                                  $item->amount     = bcmul($item->edit_money, $item->quantity, 2);
                                              }
                                          })
                                          ->toArray();                               
        if($send){
            $send_goods = $this->appendGoods($send, $store->company_id);
            $goods = array_merge($goods, $send_goods);
        }
        $order[]        = [
            "store_id"   => $param['store_id'],
            "store_name" => $store->name,
            "goods"      => $goods,
            "amount"     => array_sum(array_column($goods, 'amount')),
        ];
        $total_amount   = array_sum(array_column($order, 'amount'));
        $total_quantity = array_sum(array_column($goods, 'quantity'));
        $bill           = $store->is_on_credit === 1;
        $balance        = $this->balance;
        $large          = $this->large;
        $unique         = md5("check_order_buy_" . $this->user_id . uniqid());
        $list           = ['order' => $order, 'total_amount' => $total_amount, 'total_quantity' => $total_quantity,
                           'bill'  => $bill, 'balance' => $balance,
                           'large' => $large, 'unique' => $unique];
        Cache::set($unique, $list, 7200);
        return $this->success('成功', $list);
    }

    //修改价格
    public function salesmanEditPrice(): Response
    {
        $param = $this->request->param();
        $data  = Cache::get($param['unique']);
        // if (!$data) exception('订单不存在');
        if($data){
            // 遍历订单列表
            foreach ($data['order'] as &$order) {
                // 检查store_id是否匹配
                if ($order['store_id'] == $param['store_id']) {
                    // 遍历商品列表
                    foreach ($order['goods'] as &$goods) {
                        // 检查goods_rule_id是否匹配
                        // if ($goods['goods_rule_id'] == $param['goods_rule_id']) {
                        if ($goods['goods_rule_id'] == $param['goods_rule_id'] && $goods['is_send'] == 1) {
                            // 更新money字段
                            $goods['edit_money'] = $param['edit_money'];
                            // 也可以更新amount字段，如果需要
                            $goods['amount'] = $goods['quantity'] * $goods['edit_money'];
                        }
                    }
                    // 更新订单的总金额
                    $order['amount'] = array_sum(array_column($order['goods'], 'amount'));
                }
            }
            $data['total_amount'] = array_sum(array_column($data['order'], 'amount'));
            $unique               = md5("check_order_buy_" . $this->user_id . uniqid());
            $data['unique']       = $unique;
            Cache::set($unique, $data, 7200);
            $key = $this->user_id . '_' . $param['store_id'] . '_' . $param['goods_rule_id'];
            Cache::set($key, $param['edit_money'], 0);
        }
        
        // 2024.09.23修改价格并加入表中
        
        $time = time();
        $storeInfo = Store::field('company_id')->find($param['store_id']);
        if(!$storeInfo){
            return $this->error('门店信息有误');
        }
        $goodsRuleInfo = CompanyGoodsRule::field('goods_id, money')
                        ->where('goods_rule_id',$param['goods_rule_id'])
                        ->where('company_id',$storeInfo['company_id'])
                        ->order('id desc')
                        ->find();
        if($goodsRuleInfo){
            $editData = [
                'store_user_id' => $this->user_id,
                'store_id' => $param['store_id'],
                'goods_id' => $goodsRuleInfo['goods_id'],
                'goods_rule_id' => $param['goods_rule_id'],
                'old_money' => $goodsRuleInfo['money'],
                'new_money' => $param['edit_money'],
                'create_time' => $time,
                'update_time' => $time,
            ];
            
            $res = CompanyGoodsChangeLog::insert($editData);
        }else{
            return $this->error('商品信息有误');
        }

        return $this->success('价格修改成功', $data);
    }

    /**
     * 获取上次变动记录日志
     */
    public function getLastChangeLog($storeId, $ruleId)
    {
        $changeLog = CompanyGoodsChangeLog::field('new_money')
                    ->where('store_id', $storeId)
                    ->where('goods_rule_id', $ruleId)
                    ->where('store_user_id', $this->user_id)
                    ->order('id desc')
                    ->find();
        return $changeLog;
    }

    /**
     * 追加商品（目前只增加了赠送商品，有机会可以扩展下，普通商品也可以用这个方法，方便复用）
     */
    public function appendGoods($send, $companyId)
    {
        $sendSwitch = array_column($send, null, 'goods_rule_id');
        $send_goods = CompanyGoodsRule::where('goods_rule_id','in',array_column($send, 'goods_rule_id'))
                                    ->where('company_id', $companyId)
                                    ->withTrashed()->field('goods_id,goods_rule_id')->select()
                                    ->each(function($sendItem) use ($sendSwitch){

                                        $goods = $sendItem->goods()
                                                    ->withTrashed()
                                                    ->find();
                                        $specs = $sendItem->goodsRule()
                                                    ->withTrashed()
                                                    ->find();
                                        $sendItem->quantity       = $sendSwitch[$sendItem->goods_rule_id]['quantity'];
                                        $sendItem->money       = '0.00';
                                        $sendItem->amount       = '0.00';
                                        $sendItem->goods_name       = $goods->name;
                                        $sendItem->goods_cate_id    = $goods->goods_cate_id;
                                        $sendItem->goods_image      = $sendItem->goodsRule()
                                                                    ->withTrashed()
                                                                    ->value('img');
                                        $sendItem->spec_name        = $specs->spec_name;
                                        $sendItem->purchasing_price = $specs->purchasing_price;
                                        $sendItem->is_send = Storeorder::SEND_GOODS;
                                    })->toArray();
        return $send_goods;
    }
}